/**
 * @description: 自动生成文件方法
 * @param {type} path 生成的文件名（如/xx/a.js）
 * @return {type} tempate 模板文件
 */
const fs = require('fs')
const path = require('path')

const { resolve, log, successLog, errorLog } = require('../utils.js')

const cp = require('child_process')
const util = require('util')
const { promises } = require('dns')
// const exec = util.promisify(cp.exec)
const exec = require('shelljs').exec //|| util.promisify(require('shelljs').exec);
// 生成文件
function generateFile(path, template) {
  if (fs.existsSync(path)) {
    errorLog(`${path}文件已存在`)
  } else {
    return new Promise((resolve, reject) => {
      fs.writeFile(path, template, 'utf8', (err) => {
        if (err) {
          errorLog(err.message)
          reject(err)
        } else {
          successLog(`${path}生成成功`)
          resolve(true)
        }
      })
    })
  }
}

// 判断创建目录
function dotExistDirectoryCreate(directory) {
  return new Promise((resolve) => {
    mkdirs(directory, function () {
      resolve(true)
    })
  })
}

// 创建目录
async function mkdirs(directory, callback) {
  const exists = fs.existsSync(directory)
  if (exists) {
    // deletefolder(directory).then(() => {
    //     callback()
    // })
    callback()
  } else {
    mkdirs(path.dirname(directory), () => {
      fs.mkdirSync(directory)
      callback()
    })
  }
}

// 复制文件
function copyFile(srcPath, tarPath, cb) {
  return new Promise((resolve, reject) => {
    var rs = fs.createReadStream(srcPath)
    rs.on('error', function (err) {
      if (err) {
        console.log('read error', srcPath)
      }
      cb && cb(err)
      reject(err)
    })
    var ws = fs.createWriteStream(tarPath)
    ws.on('error', function (err) {
      if (err) {
        console.log('write error', tarPath)
      }
      cb && cb(err)
      reject(err)
    })
    ws.on('close', function (ex) {
      cb && cb(ex)
      resolve(ex)
    })
    rs.pipe(ws)
  })
}

// 拷贝文件以及目录
function copyFolder(srcDir, tarDir, cb) {
  return new Promise((resolve, reject) => {
    fs.readdir(srcDir, function (err, files) {
      var count = 0
      var checkEnd = function () {
        if (++count == files.length) {
          cb && cb()
          resolve()
        }
      }
      if (err) {
        checkEnd()
        return
      }
      files.forEach(function (file) {
        var srcPath = path.join(srcDir, file)
        var tarPath = path.join(tarDir, file)
        fs.stat(srcPath, function (err, stats) {
          if (stats.isDirectory()) {
            console.log('mkdir', tarPath)
            fs.mkdir(tarPath, function (err) {
              if (err) {
                console.log(err)
                return
              }
              copyFolder(srcPath, tarPath, checkEnd)
            })
          } else {
            copyFile(srcPath, tarPath, checkEnd)
          }
        })
      })
      //为空时直接回调
      if (files.length === 0) {
        cb && cb()
        resolve()
      }
    })
  })
}

//删除文件
function deletefile(delpath, direct) {
  delpath = direct ? delpath : resolve(delpath) // path.join(__dirname, delpath)
  try {
    /**
     * @des 判断文件或文件夹是否存在
     */
    if (fs.existsSync(delpath)) {
      fs.unlinkSync(delpath)
    } else {
      console.log('inexistence path：', delpath)
    }
  } catch (error) {
    console.log('del error', error)
  }
}

//删除目录
function deletefolder(delpath) {
  delpath = resolve(delpath) //  path.join(__dirname, delpath)
  return new Promise((resolve, reject) => {
    try {
      if (fs.existsSync(delpath)) {
        const delfn = function (address) {
          const files = fs.readdirSync(address)
          for (let i = 0; i < files.length; i++) {
            const dirpath = path.join(address, files[i])
            //fs.statSync(fullPath).isDirectory()
            if (fs.statSync(dirpath).isDirectory()) {
              delfn(dirpath)
            } else {
              deletefile(dirpath, true)
            }
          }
          /**
           * @des 只能删空文件夹
           */
          fs.rmdirSync(address)
          resolve()
        }
        delfn(delpath)
      } else {
        console.log('do not exist: ', delpath)
        resolve()
      }
    } catch (error) {
      console.log('del folder error', error)
      reject()
    }
  })
}

//下载github仓库文件内容
function gitDownFile(directory, url) {
  return new Promise(async (resolve, reject) => {
    const gitCLoneUrl = `git clone --progress --verbose --recurse-submodules ${url} ${directory}`
    try {
      console.log('克隆代码地址----->', gitCLoneUrl)
      console.log('代码克隆中···')
      await exec(gitCLoneUrl)
      console.log('代码完成')
    } catch (error) {
      console.log('gitDownFile---->', error)
    }
    resolve()
  })
}

//读取文件，并且替换文件中指定的字符串
let replaceFile = function (filePath, sourceRegx, targetStr) {
  fs.readFile(filePath, function (err, data) {
    if (err) {
      return err
    }
    let str = data.toString()
    str = str.replace(sourceRegx, targetStr)
    fs.writeFile(filePath, str, function (err) {
      if (err) return err
    })
  })
}

module.exports = {
  generateFile,
  dotExistDirectoryCreate,
  mkdirs,
  copyFile,
  copyFolder,
  deletefile,
  deletefolder,
  gitDownFile,
  replaceFile,
}
